//
//  Utils.swift
//  tverify
//
//  Created by changlei on 2023/8/15.
//

import Flutter
import Foundation
import TXLoginoauthSDK

public func toNSAttributedStringAttributes(_ dic: [String : Any]) -> [NSAttributedString.Key: Any] {
    var attributes: [NSAttributedString.Key: Any] = [:]
    for entry in dic {
        let key = NSAttributedString.Key.init(entry.key)
        switch key {
        case .font:
            attributes[key] = toUIFont(entry.value as! [String: Any])
            break
        case .link:
            attributes[key] = entry.value as! String
            break
        case .strokeColor, .underlineColor, .backgroundColor, .foregroundColor, .strikethroughColor:
            attributes[key] = toUIColor(entry.value as! [String: Any])
            break
        default:
            attributes[key] = entry.value
            break
        }
    }
    return attributes
}

public func tryToNSAttributedStringAttributes(_ dic: [String : Any]?) -> [NSAttributedString.Key: Any]? {
    guard let dic = dic else {
        return nil
    }
    return toNSAttributedStringAttributes(dic)
}

public func toNSAttributedString(_ dic: [String : Any]) -> NSAttributedString {
    let string = dic["string"] as! String
    let attributes = toNSAttributedStringAttributes(dic["attributes"] as? [String: Any] ?? [:])
    return NSAttributedString(string: string, attributes: attributes.isEmpty ? nil : attributes)
}

public func tryToNSAttributedString(_ dic: [String : Any]?) -> NSAttributedString? {
    guard let dic = dic else {
        return nil
    }
    return toNSAttributedString(dic)
}

public func toUIFont(_ dic: [String : Any]) -> UIFont {
    let size = dic["fontSize"] as! CGFloat
    if let weight = dic["fontWeight"] as? Int? {
        return UIFont.systemFont(
            ofSize: size,
            weight: UIFont.Weight(CGFloat(weight ?? 400) / 1000.0)
        )
    } else {
        return UIFont.systemFont(ofSize: size)
    }
}

public func tryToUIFont(_ dic: [String : Any]?) -> UIFont? {
    guard let dic = dic else {
        return nil
    }
    return toUIFont(dic)
}

public func toUIImage(_ data: [String : Any]) -> UIImage {
    let type = data["type"] as! String
    let imageData = data["data"]
    let package = data["package"] as? String
    let size = data["size"] as? [String: Any]
    let radius = data["radius"] as? CGFloat
    if (type == "name") {
        return UIImage.init(named: imageData as! String)!
    } else if (type == "asset") {
        return UIImage(assetName: imageData as! String, package: package)!
    } else if (type == "color") {
        return UIImage.init(color: toUIColor(imageData as! [String: Any]), size: toCGSize(size!), radius: radius!)
    } else {
        return UIImage.init(data: (imageData as! FlutterStandardTypedData).data)!
    }
}

public func tryToUIImage(_ data: [String : Any]?) -> UIImage? {
    guard let data = data else {
        return nil
    }
    return toUIImage(data)
}

public func toCGSize(_ dic: [String : Any]) -> CGSize {
    CGSize.init(
        width: dic["width"] as! CGFloat,
        height: dic["height"] as! CGFloat
    )
}

public func tryToCGSize(_ dic: [String : Any]?) -> CGSize? {
    guard let dic = dic else {
        return nil
    }
    return toCGSize(dic)
}

public func toUIColor(_ dic: [String : Any]) -> UIColor {
    UIColor.init(
        red: dic["red"] as! CGFloat,
        green: dic["green"] as! CGFloat,
        blue: dic["blue"] as! CGFloat,
        alpha: dic["alpha"] as! CGFloat
    )
}

public func tryToUIColor(_ dic: [String : Any]?) -> UIColor? {
    guard let dic = dic else {
        return nil
    }
    return toUIColor(dic)
}

public func toCGRect(_ dic: [String : Any]) -> CGRect {
    CGRect.init(
        x: dic["x"] as! CGFloat,
        y: dic["y"] as! CGFloat,
        width: dic["width"] as! CGFloat,
        height: dic["height"] as! CGFloat
    )
}

public func tryToUIEdgeInsets(_ dic: [String : Any]?) -> UIEdgeInsets? {
    guard let dic = dic else {
        return nil
    }
    return toUIEdgeInsets(dic)
}

public func toUIEdgeInsets(_ dic: [String : Any]) -> UIEdgeInsets {
    UIEdgeInsets.init(
        top: dic["top"] as! CGFloat,
        left: dic["left"] as! CGFloat,
        bottom: dic["bottom"] as! CGFloat,
        right: dic["right"] as! CGFloat
    )
}

public func tryToCGRect(_ dic: [String : Any]?) -> CGRect? {
    guard let dic = dic else {
        return nil
    }
    return toCGRect(dic)
}

public func toNSTextAlignment(_ rawValue: Int) -> NSTextAlignment {
    NSTextAlignment.init(rawValue: rawValue)!
}

public func tryToNSTextAlignment(_ rawValue: Int?) -> NSTextAlignment? {
    guard let rawValue = rawValue else {
        return nil
    }
    return toNSTextAlignment(rawValue)
}

public func toUIControlContentHorizontalAlignment(_ rawValue: Int) -> UIControl.ContentHorizontalAlignment {
    switch (toNSTextAlignment(rawValue)) {
    case .left:
        return .left
    case .right:
        return .right
    case .center:
        return .center
    default:
        return .fill
    }
}

public func tryToUIControlContentHorizontalAlignment(_ rawValue: Int?) -> UIControl.ContentHorizontalAlignment? {
    guard let rawValue = rawValue else {
        return nil
    }
    return toUIControlContentHorizontalAlignment(rawValue)
}

public extension UIImage {
    convenience init(color: UIColor, size: CGSize = CGSize(width: 1, height: 1), radius: CGFloat = 0) {
        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        let context = UIGraphicsGetCurrentContext()
        context?.setFillColor(color.cgColor)
        
        let roundedRect = CGRect(origin: .zero, size: size)
        let roundedPath = UIBezierPath(roundedRect: roundedRect, cornerRadius: radius)
        roundedPath.fill()
        
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        self.init(ciImage: CIImage(image: image!)!)
    }
    
    convenience init?(innerName: String) {
        let sdkBundle = Bundle(for: TverifyPlugin.self)
        if let path = sdkBundle.path(forResource: "TYRZResource", ofType: "bundle") {
            self.init(named: innerName, in: Bundle(path: path), compatibleWith: nil)
        } else {
            return nil
        }
    }
    
    convenience init?(assetName: String, package: String? = nil) {
        let asset: String = loadAsset(assetName, package: package)
        if let path = Bundle.main.path(forResource: asset, ofType: nil) {
            self.init(contentsOfFile: path)
        } else {
            return nil
        }
    }
    
    convenience init?(innerAssetName: String) {
        self.init(assetName: innerAssetName, package: "tverify")
    }
}

public extension UIColor {
    convenience init(hex: Int) {
        self.init(
            red: CGFloat((0x00ff0000 & hex) >> 16) / 0xFF,
            green: CGFloat((0x0000ff00 & hex) >> 8) / 0xFF,
            blue: CGFloat((0x000000ff & hex) >> 0) / 0xFF,
            alpha: CGFloat((0xff000000 & hex) >> 24) / 0xFF
        )
    }
}
